# -*- coding: utf-8 -*-
# created on 2017/3/6


from mathsolver.functions.base.base import new_latex
from mathsolver.functions.base.base import BaseValue
from mathsolver.functions.base.objects import BaseInter, BasePoint
from sympy import pi, sqrt, sympify
from sympy.abc import alpha


class BaseVectorValue(BaseValue):
    """向量变量"""

    def __init__(self, value):
        super().__init__(value)
        new_value = {}
        for key, item in value.items():
            new_value[key] = item
        self.value = new_value


class BaseXiangLiang(BaseValue):
    """向量"""

    def __init__(self, value):
        super().__init__(value)
        if isinstance(value, dict):
            self.value = value["value"]
            self.name = value["name"]
        elif isinstance(value, list):
            self.value = value
            self.name = ""
        else:
            raise ValueError()

    def sympify(self, evaluate=False):
        f1, f2 = self.value
        f1 = sympify(f1)
        f2 = sympify(f2)
        return f1, f2

    def vector2inter(self):
        return BaseInter(["("] + self.value + [")"])

    def printing(self):
        f1, f2 = self.sympify()
        return "%s(%s,%s)" % (self.name, new_latex(f1), new_latex(f2))

    def subs(self, value):
        f1, f2 = self.sympify()
        f1 = f1.subs(value)
        f2 = f2.subs(value)
        self.value = [f1, f2]
        return self

    def free_symbols(self):
        return set([s for f in self.sympify() for s in f.free_symbols])


class BaseVectorTriangle(BaseValue):
    """向量三角形"""

    def __init__(self, value):
        super().__init__(value)
        self.name = str('vTriangle')  # 类名
        assert len(value) == 3
        self.A = value[0]
        self.B = value[1]
        self.C = value[2]
        self.line_To_A_name = self.B + self.C
        self.line_To_B_name = self.A + self.C
        self.line_To_C_name = self.A + self.B
        self.line_To_A_value = sympify(self.A.lower())
        self.line_To_B_value = sympify(self.B.lower())
        self.line_To_C_value = sympify(self.C.lower())
        self.jiao_A_name = self.A
        self.jiao_A_value = sympify(self.A)
        self.jiao_B_name = self.B
        self.jiao_B_value = sympify(self.B)
        self.jiao_C_name = self.C
        self.jiao_C_value = sympify(self.C)
        self.vEqs = []
        self.value = None

    def condition_transform(self):
        from mathsolver.functions.xiangliang.basic import XLTriangleConditionTransform
        answer = XLTriangleConditionTransform().solver(self.vEqs).output[0].sympify()
        if self.line_To_A_value in answer:
            self.line_To_A_value = list(answer[self.line_To_A_value])[0]
        if self.line_To_B_value in answer:
            self.line_To_B_value = list(answer[self.line_To_B_value])[0]
        if self.line_To_C_value in answer:
            self.line_To_C_value = list(answer[self.line_To_C_value])[0]
        if self.jiao_A_value in answer:
            self.jiao_A_value = list(answer[self.jiao_A_value])[0]
        if self.jiao_B_value in answer:
            self.jiao_B_value = list(answer[self.jiao_B_value])[0]
        if self.jiao_C_value in answer:
            self.jiao_C_value = list(answer[self.jiao_C_value])[0]
        pass


class BaseVectorSanJiaoXing(BaseValue):
    """向量三角形"""
    def __init__(self, p1, p2, p3):
        super().__init__()
        self.point_A_name = p1
        self.point_B_name = p2
        self.point_C_name = p3
        self.point_A_Axis = None
        self.point_B_Axis = None
        self.point_C_Axis = None
        self.point_Gravity_name = None   # 重心
        self.point_Gravity_Axis = None
        self.line_To_A_name = self.point_B_name + self.point_C_name
        self.line_To_B_name = self.point_A_name + self.point_C_name
        self.line_To_C_name = self.point_A_name + self.point_B_name
        self.line_To_A_value = sympify(self.point_A_name.lower())
        self.line_To_B_value = sympify(self.point_B_name.lower())
        self.line_To_C_value = sympify(self.point_C_name.lower())
        self.Angle_A_name = p1
        self.Angle_B_name = p2
        self.Angle_C_name = p3
        self.Angle_A_value = None
        self.Angle_B_value = None
        self.Angle_C_value = None
        self.Area = None
        self.point_Neixin_name = None    # 内心
        self.point_Neixin_Axis = None
        self.point_Waixin_name = None  # 外心
        self.point_Waixin_Axis = None
        self.WaiBanJing_value = None
        self.Eqs = []
        self.value = None
        self.type = str('vTriangle')  # 三角形类别
        self.name = p1 + p2 + p3  # 类名

    def eqs_update(self, items):
        eqs = items.sympify()
        for eq in eqs:
            if eq not in self.Eqs:
                self.Eqs.append(eq)

    def eq_update(self, item):
        eq = item.sympify()
        if eq not in self.Eqs:
            self.Eqs.append([eq[0], eq[1]])

    def get_gravity_axis(self):
        point_a_axis = self.point_A_Axis.sympify()
        point_b_axis = self.point_B_Axis.sympify()
        point_c_axis = self.point_C_Axis.sympify()
        point_gravity_axis = BasePoint({"name": self.point_Gravity_name,
                                        "value": [(point_a_axis[0] + point_b_axis[0] + point_c_axis[0])/3,
                                                  (point_a_axis[1] + point_b_axis[1] + point_c_axis[1])/3]})
        self.point_Gravity_Axis = point_gravity_axis

    def get_waibanjing_eqs(self):
        point_waixin_name = self.point_Waixin_name
        point_a_name = self.point_A_name
        point_b_name = self.point_B_name
        point_c_name = self.point_C_name
        vector_1 = "vector" + "(" + point_waixin_name + point_a_name + ")"
        vector_1 = sympify(vector_1)
        vector_2 = "vector" + "(" + point_waixin_name + point_b_name + ")"
        vector_2 = sympify(vector_2)
        vector_3 = "vector" + "(" + point_waixin_name + point_c_name + ")"
        vector_3 = sympify(vector_3)
        self.Eqs.append([vector_1 * vector_1, vector_2 * vector_2])
        self.Eqs.append([vector_1 * vector_1, vector_3 * vector_3])
        self.Eqs.append([vector_2 * vector_2, vector_3 * vector_3])


class BaseVectorRectangularTriangle(BaseVectorSanJiaoXing):
    """向量直角三角形"""
    def __init__(self, p1, p2, p3):
        BaseVectorSanJiaoXing.__init__(self, p1, p2, p3)
        self.type = str('vRectangularTriangle')  # 三角形类别
        self.Angle_Rectangular_name = None

    def get_gougudingli(self):
        if self.Angle_Rectangular_name == self.point_A_name:
            self.Eqs.append([self.line_To_B_value ** 2 + self.line_To_C_value ** 2, self.line_To_A_value ** 2])
        elif self.Angle_Rectangular_name == self.point_B_name:
            self.Eqs.append([self.line_To_A_value ** 2 + self.line_To_C_value ** 2, self.line_To_B_value ** 2])
        else:
            self.Eqs.append([self.line_To_A_value ** 2 + self.line_To_B_value ** 2, self.line_To_C_value ** 2])


class BaseVectorIsOscelesRectangularTriangle(BaseVectorRectangularTriangle):
    """向量等腰直角三角形"""
    def __init__(self, p1, p2, p3):
        BaseVectorSanJiaoXing.__init__(self, p1, p2, p3)
        self.type = str('vIsoscelesRectangularTriangle')  # 三角形类别
        self.Angle_Rectangular_name = None

    def get_is_osceles_eq(self):
        if self.Angle_Rectangular_name == self.point_A_name:
            self.Eqs.append([self.line_To_B_value, self.line_To_C_value])
        elif self.Angle_Rectangular_name == self.point_B_name:
            self.Eqs.append([self.line_To_A_value, self.line_To_C_value])
        else:
            self.Eqs.append([self.line_To_A_value, self.line_To_B_value])


class BaseVectorRegularTriangle(BaseVectorSanJiaoXing):
    """向量正三角形"""
    def __init__(self, p1, p2, p3):
        BaseVectorSanJiaoXing.__init__(self, p1, p2, p3)
        self.type = str('vRegularTriangle')  # 类名
        self.edge_length = None
        self.Angle_A_value = pi / 3
        self.Angle_B_value = pi / 3
        self.Angle_C_value = pi / 3

    def get_area_eq(self):
        line_to_a_value = self.line_To_A_value
        self.Eqs.append([sqrt(3) * line_to_a_value ** 2 / 4, self.Area])


class BaseVectorCircumCenterTriangle(BaseVectorSanJiaoXing):
    """向量+三角形+外心"""
    def __init__(self, triangle_points):
        BaseVectorSanJiaoXing.__init__(self, *triangle_points)
        self.name = str('vCircumcenterTriangle')  # 类名
        self.CircumCenter = None
        self.CircumCenter_Axis = None
        self.CircumCircle_R = None


class BaseVectorQuadra(BaseValue):
    """向量四边形"""
    def __init__(self, p1, p2, p3, p4):
        super().__init__()
        self.point_A_name = p1
        self.point_B_name = p2
        self.point_C_name = p3
        self.point_D_name = p4
        self.point_A_Axis = None
        self.point_B_Axis = None
        self.point_C_Axis = None
        self.point_D_Axis = None
        self.Angle_A_name = p1
        self.Angle_B_name = p2
        self.Angle_C_name = p3
        self.Angle_D_name = p4
        self.Angle_A_value = None
        self.Angle_B_value = None
        self.Angle_C_value = None
        self.Angle_D_value = None
        self.line_AB_name = self.point_A_name + self.point_B_name
        self.line_BC_name = self.point_B_name + self.point_C_name
        self.line_CD_name = self.point_C_name + self.point_D_name
        self.line_DA_name = self.point_D_name + self.point_A_name
        self.line_AB_value = None
        self.line_BC_value = None
        self.line_CD_value = None
        self.line_DA_value = None
        self.Eqs = []
        self.Area = None
        self.value = None
        self.type = str('vQuadra')  # 类名
        self.name = p1 + p2 + p3 + p4

    def eqs_update(self, items):
        eqs = items.sympify()
        for eq in eqs:
            if eq not in self.Eqs:
                self.Eqs.append(eq)

    def eq_update(self, item):
        eq = item.sympify()
        if eq not in self.Eqs:
            if len(eq) == 2:
                self.Eqs.append([eq[0], eq[1]])
            else:
                self.Eqs.append([eq[0], eq[1], eq[2]])


class BaseVectorSquare(BaseVectorQuadra):
    """向量正方形"""
    def __init__(self, p1, p2, p3, p4):
        BaseVectorQuadra.__init__(self, p1, p2, p3, p4)
        self.type = str('vSquare')  # 类名
        self.edge_length = None
        self.Angle_A_value = pi / 2
        self.Angle_B_value = pi / 2
        self.Angle_C_value = pi / 2
        self.Angle_D_value = pi / 2

    def get_area_eq(self):
        edge_length = self.edge_length
        self.Eqs.append([edge_length ** 2, self.Area])


class BaseVectorDiamond(BaseVectorQuadra):
    """向量棱形"""
    def __init__(self, p1, p2, p3, p4):
        BaseVectorQuadra.__init__(self, p1, p2, p3, p4)
        self.edge_length = None
        self.type = str('vDiamond')  # 类名

    def angle_init(self):
        if self.Angle_A_value:
            self.Angle_B_value = pi - self.Angle_A_value
            self.Angle_C_value = self.Angle_A_value
            self.Angle_D_value = self.Angle_B_value
        elif self.Angle_B_value:
            self.Angle_A_value = pi - self.Angle_B_value
            self.Angle_C_value = self.Angle_A_value
            self.Angle_D_value = self.Angle_B_value
        elif self.Angle_C_value:
            self.Angle_A_value = self.Angle_C_value
            self.Angle_B_value = pi - self.Angle_A_value
            self.Angle_D_value = self.Angle_B_value
        elif self.Angle_D_value:
            self.Angle_B_value = self.Angle_D_value
            self.Angle_A_value = pi - self.Angle_B_value
            self.Angle_C_value = self.Angle_A_value
        else:
            self.Angle_A_value = 2 * alpha
            self.Angle_B_value = pi - self.Angle_A_value
            self.Angle_C_value = self.Angle_A_value
            self.Angle_D_value = self.Angle_B_value


class BaseVectorRectangle(BaseVectorQuadra):
    """向量矩形"""
    def __init__(self, p1, p2, p3, p4):
        BaseVectorQuadra.__init__(self, p1, p2, p3, p4)
        self.length = None
        self.type = str('vRectangle')  # 类名
        self.Angle_A_value = pi / 2
        self.Angle_B_value = pi / 2
        self.Angle_C_value = pi / 2
        self.Angle_D_value = pi / 2


class BaseVectorIsOscelesTrapezoid(BaseVectorQuadra):
    """向量等腰梯形"""
    def __init__(self, quadra_points):
        BaseVectorQuadra.__init__(self, *quadra_points)
        self.type = str('vIsOscelesTrapezoid')  # 类名
        self.base_line = None
        self.up_line = None
